package com.google.code.virtualhockey.vhx.client.srvcom;

import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.http.client.*;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.gwt.user.client.Window;

/**
 * Dispatches commands to a server side service using a HTTP GET request.
 */
public class CommandDispatcher {

  private final String m_strServiceUrl;

  /**
   * Creates a new CommandDispatcher.
   *
   * @param strUrl the URL of the service that handles the dispatched commands
   */
  public CommandDispatcher( String strUrl ) {
    m_strServiceUrl = strUrl;
  }

  public void dispatch( final Command cmd, final CommandCallback<?> callback ) {
    RequestBuilder requestBuilder = new RequestBuilder( RequestBuilder.POST, m_strServiceUrl );

    requestBuilder.setHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
    requestBuilder.setHeader( "x-vhx-command", cmd.getName() );
    requestBuilder.setHeader( "x-vhx-locale", LocaleInfo.getCurrentLocale().getLocaleName() );
    requestBuilder.setRequestData( URL.encode( createRequestData( cmd ) ) );

    try {
      requestBuilder.sendRequest( null, new RequestCallback() {
        @Override
        public void onResponseReceived( Request request, Response responseRaw ) {
          CommandResponse responseCmd = JsonUtils.safeEval( responseRaw.getText() );

          if ( responseCmd.isOk() )
            callback.onSuccess( responseCmd );
          else
            callback.onFailure( responseCmd );
        }

        /**
         * Handles a fatal error which results when the request does not even reach the server.
         *
         * @param request the request object which has experienced the error
         *     condition, may be null if the request was never generated
         * @param throwable
         */
        @Override
        public void onError( Request request, Throwable throwable ) {
          callback.onFatal( cmd, throwable );
        }
      } );
    } catch ( RequestException ex ) {
      // TODO user GWT logging
      Window.alert( "CommandDispatcher#dispatch() exception: " + ex.getMessage() );
    }
  }

  private String createRequestData( Command cmd ) {
    StringBuilder sb = new StringBuilder();

    for ( String strKey : cmd.getParamters().keySet() ) {
      if ( sb.length() > 0 )
        sb.append( "&" );
      sb.append( strKey ).append( "=" ).append( cmd.getParameter( strKey ) );
    }

    return sb.toString();
  }
}
